module matrix_regs(
input wire clk,
input wire rst,

input w_m_en,
input r_m_en,
// w: ld.tile mov.tile; r: st.tile mov.tile rd;
input wire [1:0] w_m_index,
input wire [1:0] r_m_index,

input wire [31:0] w_m_data,

output wire [31:0] r_m_data,

input wire w_matrix_mopa_en,
//mopa 
input wire [31:0] w_matrix_mopa [3:0],
output wire [31:0] r_matrix_mopa [3:0],
// ex-mem test 6
input wire me_matrix_mopa_en,
input wire[31:0] me_matrix_mopa_o[3:0]

);

reg [31:0] M [3:0]; //matrix regs
always @(posedge clk)begin
if (!rst) begin
M[0] <= 32'h55555555;
M[1] <= 32'haaaaaaaa;
M[2] <= 32'h33333333;
M[3] <= 32'hcccccccc;
end
else if (w_m_en) begin
M[w_m_index] <= w_m_data;
end
else if(w_matrix_mopa_en)begin
M[0] <= w_matrix_mopa[0];
M[1] <= w_matrix_mopa[1];
M[2] <= w_matrix_mopa[2];
M[3] <= w_matrix_mopa[3];
end
end

// if read and write use same time, forward;
assign r_m_data = (r_m_en && w_matrix_mopa_en && r_m_index == 2'b00) ? w_matrix_mopa[0] :
		(r_m_en && w_matrix_mopa_en && r_m_index == 2'b01) ? w_matrix_mopa[1] :
		(r_m_en && w_matrix_mopa_en && r_m_index == 2'b10) ? w_matrix_mopa[2] :
		(r_m_en && w_matrix_mopa_en && r_m_index == 2'b11) ? w_matrix_mopa[3] :

                (r_m_en && me_matrix_mopa_en && r_m_index == 2'b00) ? me_matrix_mopa_o[0] :
                (r_m_en && me_matrix_mopa_en && r_m_index == 2'b01) ? me_matrix_mopa_o[1] :
                (r_m_en && me_matrix_mopa_en && r_m_index == 2'b10) ? me_matrix_mopa_o[2] :
                (r_m_en && me_matrix_mopa_en && r_m_index == 2'b11) ? me_matrix_mopa_o[3] :

		(r_m_en && w_m_index == r_m_index && w_m_en) ? w_m_data : 
		(r_m_en) ? M[r_m_index] : 32'h00000000;

//test6 mov.tile and mopa chongtu
assign r_matrix_mopa[0] = (r_m_en && w_m_en && w_m_index == 2'b00)? w_m_data: M[0];
assign r_matrix_mopa[1] = M[1];
assign r_matrix_mopa[2] = M[2];
assign r_matrix_mopa[3] = M[3];


endmodule
